package se.kth.ict.id2203.beb;

import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import se.kth.ict.id2203.pp2p.PerfectPointToPointLink;
import se.kth.ict.id2203.pp2p.Pp2pSend;
import se.sics.kompics.ComponentDefinition;
import se.sics.kompics.Handler;
import se.sics.kompics.Negative;
import se.sics.kompics.Positive;
import se.sics.kompics.address.Address;
import se.sics.kompics.launch.Topology;

public class BEB extends ComponentDefinition {
	
	Negative<BestEffortBroadcast> beb = provides(BestEffortBroadcast.class);
	Positive<PerfectPointToPointLink> pp2p = requires(PerfectPointToPointLink.class);
	
	private Address self;
	private Topology topology;
	private Set<Address> processSet;
	
	private static final Logger logger =
			LoggerFactory.getLogger(BEB.class);
	
	public BEB() {
		logger.info("BEB created.");
		subscribe(handleInit, control);
		subscribe(handleBebBroadcast, beb);
		subscribe(handleBebMessage, pp2p);
	
	}
	
	Handler<BEBInit> handleInit = new Handler<BEBInit>() {
		public void handle(BEBInit event) {
			logger.info("BEB started.");
			topology = event.getTopology();
			self = topology.getSelfAddress();
			processSet = topology.getAllAddresses();
		}
	};
	
	Handler<BebBroadcast> handleBebBroadcast = new Handler<BebBroadcast>() {
		public void handle(BebBroadcast event) {
			
			for (Address process : processSet) {
				trigger(new Pp2pSend(process, new BebMessage(self, event.getDeliverEvent())), pp2p);
				logger.info("Broadcast to " + process);
			}			
		}
	};
	
	Handler<BebMessage> handleBebMessage = new Handler<BebMessage>() {
		public void handle(BebMessage event) {			
			logger.info("BebMessage received from " + event.getSource());
			trigger(event.getDeliverEvent(), beb);			
		}
	};
}
